﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ShprossesBuilder.Editor;
using ITAP.ShprossesBuilder.Modelling.Components;
using ITAP.ShprossesBuilder.Calculations;
using ITAP.ShprossesBuilder.Properties;
using ITAP.Core.Calculations;

namespace ITAP.ShprossesBuilder.Operations
{
    public class OperationCreateShprossBetweenShprossConnectors : IOperation
    {
        #region IOperation Members

        public string Name
        {
            get { return "Соединить выбранные соединители профилем"; }
        }

        public OperationGroup OperationGroup
        {
            get { return OperationGroup.Other; }
        }

        public System.Drawing.Image Thumbnail
        {
            get { return Resources.CreateShprossBetweenShprossConnectors.ToBitmap(); }
        }

        public void Execute(ModelControl modelControl)
        {
            if(modelControl.ModelContainer.SelectedComponentsStack.Count <= 1)
                return;

            List<ShprossConnector> shprossConnectors = new List<ShprossConnector>();            

            foreach (IComponent selectedComponent in modelControl.ModelContainer.SelectedComponentsStack)
            {
                if (selectedComponent is ShprossConnector)
                {
                    shprossConnectors.Add(selectedComponent as ShprossConnector);
                }
            }

            ShprossConnector prevConnector = shprossConnectors[0];
            for (int i = 1; i < shprossConnectors.Count; i++)
            {
                ShprossConnector currConnector = shprossConnectors[i];
                if (prevConnector.Parent != currConnector.Parent)
                    return;
                prevConnector = currConnector;
            }

            SelectMaterialForm selectShpross = new SelectMaterialForm();
            selectShpross.Initialize(modelControl.ProfileProvider, new Material[] { Material.Shpross }, false, "Выберите профиль", false);
            if (selectShpross.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;

            prevConnector = shprossConnectors[0];
            for (int i = 1; i < shprossConnectors.Count; i++)
            {
                ShprossConnector currConnector = shprossConnectors[i];
                Connector connector1 = null;
                Connector connector2 = null;
                double distance = double.MaxValue;
                foreach (IComponent inner1 in prevConnector.InnerComponents)
                {
                    if (inner1.GetType() != typeof(Connector))
                        continue;

                    if ((inner1 as Connector).Occupied)
                        continue;

                    foreach (IComponent inner2 in currConnector.InnerComponents)
                    {
                        if (inner2.GetType() != typeof(Connector))
                            continue;

                        if ((inner2 as Connector).Occupied)
                            continue;

                        double currentDistance = ModelCalculations.GetDistance(inner1.Position, inner2.Position);
                        if (currentDistance < distance)
                        {
                            distance = currentDistance;
                            connector1 = inner1 as Connector;
                            connector2 = inner2 as Connector;
                        }
                    }
                }

                if (connector1 == null || connector2 == null)
                    continue;

                Shpross shpross = selectShpross.SelectedComponent as Shpross;
                shpross = shpross.Copy() as Shpross;
                shpross.SerialNumber = 0;
                shpross.MoveStartPointTo(connector1.StartPoint);
                shpross.MoveEndPointTo(connector2.StartPoint);
                currConnector.Parent.AddInnerComponent(shpross);
                modelControl.UpdateModel();
                prevConnector = currConnector;
            }
        }

        public bool CanUndo
        {
            get { return true; }
        }

        #endregion
    }
}
